﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Reflection.Emit;
using System.Text;

namespace CRL.Data
{
    public partial class PropertyBuilder<T>
    {
        public PropertyBuilder<T> Relation<TJoin>(Expression<Func<T, TJoin, bool>> expression)
        {
            GetRelationInfo(expression);
            return this;
        }

        RelationInfo GetRelationInfo<TJoin>(Expression<Func<T, TJoin, bool>> expression)
        {
            var be = (BinaryExpression)expression.Body;
            var left = (MemberExpression)be.Left;
            var right = (MemberExpression)be.Right;
            var relationInfo = new RelationInfo
            {
                Type1 = left.Member.DeclaringType,
                Type1Field = TypeCache.GetTable(left.Member.DeclaringType).FieldsDic[left.Member.Name],
                Type2 = right.Member.DeclaringType,
                Type2Field = TypeCache.GetTable(right.Member.DeclaringType).FieldsDic[right.Member.Name],
                expression = expression.Body,
                parameters = expression.Parameters
            };
            var relationInfo2 = new RelationInfo
            {
                Type2 = left.Member.DeclaringType,
                Type2Field = TypeCache.GetTable(left.Member.DeclaringType).FieldsDic[left.Member.Name],
                Type1 = right.Member.DeclaringType,
                Type1Field = TypeCache.GetTable(right.Member.DeclaringType).FieldsDic[right.Member.Name],
                expression = expression.Body,
                parameters = expression.Parameters
            };
            if (!relationCahe.ContainsKey(relationInfo.Key1))
            {
                relationCahe.Add(relationInfo.Key1, relationInfo);
            }
            if (!relationCahe.ContainsKey(relationInfo.Key2))
            {
                relationCahe.Add(relationInfo.Key2, relationInfo2);
            }
            return relationInfo;
        }
     
    }
    internal class RelationInfo
    {
        public Type Type1;
        public Type Type2;
        public Attribute.FieldInnerAttribute Type1Field;
        public Attribute.FieldInnerAttribute Type2Field;
        public Expression expression;
        public ReadOnlyCollection<ParameterExpression> parameters;
        public string Key1
        {
            get
            {
                return $"{Type1}_{Type2}";
            }
        }
        public string Key2
        {
            get
            {
                return $"{Type2}_{Type1}";
            }
        }
    }
}
